package com.amat0urheu.service.impl;

import com.amat0urheu.dao.*;

import com.amat0urheu.pojo.*;
import com.amat0urheu.pojo.CloudPojo.VMservice;
import com.amat0urheu.service.ExpeImageService;
import com.amat0urheu.service.ExperimentService;
import com.amat0urheu.util.CommonUtil;
import com.amat0urheu.util.generator.SnowFlakeUtil;
import com.amat0urheu.utils.CloudUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;


@Service
public class ExperimentServiceImpl  implements ExperimentService {
    final ExperimentsMapper experimentsMapper;
    final ExperimentSceneMapper experimentSceneMapper;
    @Autowired
    SceneMapper sceneMapper;
    @Autowired
    CloudMapper cloudMapper;
    @Autowired
    public ExperimentServiceImpl(ExperimentsMapper experimentsMapper, ExperimentSceneMapper  experimentSceneMapper) {
        this.experimentsMapper = experimentsMapper;
        this.experimentSceneMapper=experimentSceneMapper;

    }


    @Override
    public ReturnRes    getExperimentpage(int pageSize, int pageNum) {

        PageHelper.startPage(pageNum, pageSize);
        List<Experiment> experiments = experimentsMapper.selectExperimentByPage();

        if (experiments != null) {
            return new ReturnRes(true, new PageInfo<>(experiments), "查询成功");
        }

        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes getExperimentByIdForUser(String id) {

             Experiment experiment=   experimentsMapper.getExperimentByIdForUser(id);
        if (experiment != null) {
            return new ReturnRes(true, experiment, "查询成功");
        }
        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes updateExperiment(Experiment experiment) {


        if(  experimentsMapper.updateExperiment(experiment)>0){
            return  new ReturnRes(true, "更新成功");
        }
        return  new ReturnRes(false, "更新失败");
    }

    @Override
    public ReturnRes getExperimentAndScene(int pageSize, int pageNum) {
        PageHelper.startPage(pageNum, pageSize);

        List<ExperimentScene> experimentScene = experimentSceneMapper.selectExperimentScenePage();

        if (experimentScene != null) {
            return new ReturnRes(true, new PageInfo<>(experimentScene), "查询成功");
        }

        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes removegetExperimentAndScene(Integer id) {

       int count= experimentSceneMapper.removeExperimentScene(id);
       if(count!=0){
           return new ReturnRes(true, "删除成功");
       }
        return new ReturnRes(true, "删除失败");
    }

    @Override
    public ReturnRes getAllExperimentVm(int pageSize, int pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        List<VMservice> experimentVms = experimentsMapper.selectExperimentVMByPage();
        if (experimentVms != null) {
            return new ReturnRes(true, new PageInfo<>(experimentVms), "查询成功");
        }

        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes applyVmServerForUser(String experimentName, String name) {
        int havaVmOfUser=experimentsMapper.judgeIfHaveVMOfExperiment(experimentName,name);
        if(havaVmOfUser!=0){
            return new ReturnRes(false, "申请失败，同一时间只能申请一个实验的虚拟环境");
        }
        Date releaseTime = experimentsMapper.getReleaseTime(name);
        if(releaseTime!=null){
            Date currentTime = new Date();
            System.err.println(releaseTime+" "+currentTime);
            long timeDifference = currentTime.getTime()-releaseTime.getTime() ;
            long hoursDifference = timeDifference / (60 * 60 * 1000);
            if (hoursDifference < 1) {
                return new ReturnRes(false, "申请失败，正在冷却中,冷却时间:"+(60-timeDifference/60000));
            }

        }
        int count=experimentsMapper.selectCountNoUser(experimentName);

        if(count>0){
            int proxyNum= experimentsMapper.findProxyNumNoUser(experimentName);
            if(proxyNum!=0){
                experimentsMapper.setVmServerForUser(name,proxyNum);
            }
            return new ReturnRes(true,"申请成功");
        }
        return new ReturnRes(false, "申请失败，可能资源不足，或者资源已经过期请联系老师");
    }

    @Override
    public ReturnRes getExperimentVmsforUser(String name,Integer id) {
        String experimentName= experimentsMapper.getExperimentName(id);
        List<VMservice> experimentVms = experimentsMapper.getExperimentVmsforUser(name,experimentName);


        if (experimentVms != null) {
            return new ReturnRes(true, new PageInfo<>(experimentVms), "查询成功");
        }

        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes getexperiments() {

        List<Experiment> experiments =experimentsMapper.getAllExperiments();
        if (experiments != null) {
            return new ReturnRes(true, new PageInfo<>(experiments), "查询成功");
        }

        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes saveExperimentAndSceneAdd(Integer experimentId,Integer sceneId ) {

        int count =experimentSceneMapper.insertExperimentScene(experimentId,sceneId);
        if (count>0) {
            return new ReturnRes(true, "添加成功");
        }

        return new ReturnRes(false, "添加失败");
    }

    @Override
    public ReturnRes removeExperimentAndScene(Integer id) {
        int count = experimentSceneMapper.removeExperimentScene(id);
        if(count>0){   return new ReturnRes(true, "删除成功");}
        return new ReturnRes(false, "删除失败");
    }

    @Override
    public ReturnRes ExperimentAndSceneupdate(ExperimentScene experimentScene) {

        int count=experimentSceneMapper.updateExperimentScene(experimentScene);

        if(count>0){
            return new ReturnRes(true, "更新成功");
        }
        return new ReturnRes(false, "更新失败");
    }

    @Override
    public ReturnRes getExperimentScores(int pageSize, int pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        List<Experiment> experiments = experimentsMapper.selectExperimentByPage();
        if (experiments != null) {
            return new ReturnRes(true, new PageInfo<>(experiments), "查询成功");
        }

        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes getAllExperiments() {
        List<Experiment> experiments = experimentsMapper.getExperimentNamesAndId();

        if (experiments != null) {
            return new ReturnRes(true, new PageInfo<>(experiments), "查询成功");
        }

        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes getAllUserScores(int pageSize, int pageNum) {
        PageHelper.startPage(pageNum, pageSize);
        List<ExperimentScores> experimentScores = experimentsMapper.getAllUserScores();
        for (int i=0;i<experimentScores.size();i++){
            List<Experiment> experimentNamesAndId = experimentsMapper.getExperimentNamesAndId();
            HashMap<String, Integer> experimentSCoreMap = new HashMap<>();
            for (Experiment e:experimentNamesAndId ) {
                Integer score= experimentsMapper.getScoreOfExperiment(e.getEid(),experimentScores.get(i).getUid());

                if(score==null){
                    experimentSCoreMap.put(e.getEname(),0);
                }else {
                    experimentSCoreMap.put(e.getEname(),score);
                }
            }
            experimentScores.get(i).setExperimentScores(experimentSCoreMap);

        }

        if (experimentScores != null) {
            return new ReturnRes(true, new PageInfo<>(experimentScores), "查询成功");
        }

        return new ReturnRes(false, "查询失败");
    }

    @Override
    public ReturnRes updateUserScore(ExperimentScores experimentScores) {


        //插入平时分和报告分数
        int count =experimentsMapper.updateSconre(experimentScores.getUid(),experimentScores.getRoutineScore(),experimentScores.getReportScore());

        //循环插入实验的分数
        for (Map.Entry<String, Integer> entry : experimentScores.getExperimentScores().entrySet()) {
            String  key = entry.getKey();
            Integer experimentId = experimentsMapper.getExperimentId(key);
            Integer experimentScore = entry.getValue();
            int num=experimentsMapper.judegeExit(experimentScores.getUid(),experimentId);
            if(num>0){
                experimentsMapper.updateExperimentScore(experimentScores.getUid(),experimentId,experimentScore);
            }else {


                experimentsMapper.insertExperimentScore(experimentScores.getUid(),experimentId,experimentScore);
            }
            // 在这里处理 key 和 value
        }
        return new ReturnRes(true,"成绩更新成功");
    }

    @Override
    public ReturnRes searchExperimentForAdmin(String key, String value, int pageNum, int pageSize) {

        PageHelper.startPage(pageNum, pageSize);
        String[] whiteList = new String[]{"ename"};
        if (CommonUtil.strArrayIsHave(whiteList, key)) {
            List<Experiment>  experimentList = experimentsMapper.searchExperiment(key, "%" + value + "%");
            if (experimentList != null) {
                return new ReturnRes(true, new PageInfo<>(experimentList), "查询成功");
            } else {
                return new ReturnRes(false, "查询失败");
            }
        } else {
            return new ReturnRes(false, "师傅请勿尝试不安全的参数");
        }
    }

    @Override
    public ReturnRes searchExperimentAndSceneForAdmin(String key, String value, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        String[] whiteList = new String[]{"ename", "scene"};
        if (CommonUtil.strArrayIsHave(whiteList, key)) {
            List<ExperimentScene>  experimentSceneList = experimentSceneMapper.searchExperimentAndSceneForAdmin(key, "%" + value + "%");

            if (experimentSceneList != null) {
                return new ReturnRes(true, new PageInfo<>(experimentSceneList), "查询成功");
            } else {
                return new ReturnRes(false, "查询失败");
            }
        } else {
            return new ReturnRes(false, "师傅请勿尝试不安全的参数");
        }
    }

    @Override
    public ReturnRes searchExperimentScorePage(String key, String value, int pageNum, int pageSize) {

        PageHelper.startPage(pageNum, pageSize);
        String[] whiteList = new String[]{"uname"};

        if (CommonUtil.strArrayIsHave(whiteList, key)) {
            List<ExperimentScores> experimentScores = experimentsMapper.getUserScores(key, "%" + value + "%");
            for (int i=0;i<experimentScores.size();i++){
                List<Experiment> experimentNamesAndId = experimentsMapper.getExperimentNamesAndId();
                HashMap<String, Integer> experimentSCoreMap = new HashMap<>();
                for (Experiment e:experimentNamesAndId ) {
                    Integer score= experimentsMapper.getScoreOfExperiment(e.getEid(),experimentScores.get(i).getUid());

                    if(score==null){
                        experimentSCoreMap.put(e.getEname(),0);
                    }else {
                        experimentSCoreMap.put(e.getEname(),score);
                    }
                }
                experimentScores.get(i).setExperimentScores(experimentSCoreMap);
            }
            if (experimentScores != null) {
                return new ReturnRes(true, new PageInfo<>(experimentScores), "查询成功");
            } else {
                return new ReturnRes(false, "查询失败");
            }
        } else {
            return new ReturnRes(false, "师傅请勿尝试不安全的参数");
        }
    }

    @Override
    public ReturnRes searchExperimentVmPage(String key, String value, int pageNum, int pageSize) {

        PageHelper.startPage(pageNum, pageSize);
        String[] whiteList = new String[]{"proxyNum", "experiment","user"};
        if (CommonUtil.strArrayIsHave(whiteList, key)) {
            List<VMservice> vmList = experimentSceneMapper.searchRaceVmForAdmin(key, "%" + value + "%");

            if (vmList != null) {
                return new ReturnRes(true, new PageInfo<>(vmList), "查询成功");
            } else {
                return new ReturnRes(false, "查询失败");
            }
        } else {
            return new ReturnRes(false, "师傅请勿尝试不安全的参数");
        }
    }


    @Override
    public ReturnRes saveExperiment(Experiment experiment) {

        int count=experimentsMapper.getCountByEname(experiment.getEname());
        if(count>0){
            return  new ReturnRes(false, "该实验已存在");
        }
        experimentsMapper.saveExperiment(experiment);
        return  new ReturnRes(true, "保存成功");
    }
    @Value("${marsctf.uploadPath}")
    private String uploadPath;

    @Value("${marsctf.imagePath}")
    private String imagePath;

    @Value("${marsctf.imageUrl}")
    private String imageUrl;
    @Autowired
    ExpeImageService expeImageService;
    @Override
    public ReturnRes uploadImageForExperiment(MultipartFile file, Integer eid) {
        if (file.isEmpty()) {
            return new ReturnRes(false, "上传失败，请选择文件");
        }
        String fileName = file.getOriginalFilename();
        int lastIndexOf = fileName.lastIndexOf(".");
        String ext = lastIndexOf != -1 ? fileName.substring(lastIndexOf + 1) : "";
        String newName = String.valueOf(SnowFlakeUtil.generatorUid()) + "." + ext;
        File dest = new File(imagePath + imageUrl, newName);
        try {
            ExperimentImage exImage = new ExperimentImage();
            exImage.setEid(eid);
            exImage.setFpath(newName);
            expeImageService.save(exImage);
            file.transferTo(dest);  // 上传成功
            return new ReturnRes(true, imageUrl + newName, "图片上传成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ReturnRes(false, "上传失败，服务器错误");
    }

    @Override
    public ReturnRes getExperimentvmCount() {
        List<String> experiments=experimentSceneMapper.getAllExperiments();
        List<VmCount>  vmCountList=new ArrayList<>();
        for (int i=0;i<experiments.size();i++){
            VmCount vmCount = new VmCount();
            int vmSum=experimentSceneMapper.getVmSumofExperiment(experiments.get(i));
            int usingCount=experimentSceneMapper.getVmUsingofExperiment(experiments.get(i));
            vmCount.setSum(vmSum);
            vmCount.setUsing(usingCount);
            vmCount.setName(experiments.get(i));
            vmCountList.add(vmCount);
        }
        System.err.println(vmCountList);
        if(   vmCountList.size() >=1){
            return new ReturnRes(true, new PageInfo<>(vmCountList), "查询成功");
        }
        return new ReturnRes(false, "暂无查找到资源");
    }
    @Override
    public void downloadScoreFile(HttpServletResponse response) {
        List<ExperimentScores> experimentScores = getUsersScores();
        List<Experiment> experimentNamesAndId = experimentsMapper.getExperimentNamesAndId();

        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("成绩表");
        Row headerRow = sheet.createRow(0);
        headerRow.createCell(0).setCellValue("序号");
        headerRow.createCell(1).setCellValue("学号");
        headerRow.createCell(2).setCellValue("平时成绩");
        headerRow.createCell(3).setCellValue("报告成绩");

        for (int i = 4; i < experimentNamesAndId.size() + 4; i++) {
            headerRow.createCell(i).setCellValue(experimentNamesAndId.get(i - 4).getEname());
        }

        int rowNum = 1;
        for (ExperimentScores student : experimentScores) {
            Row scoreRow = sheet.createRow(rowNum++);
            scoreRow.createCell(0).setCellValue(rowNum);
            scoreRow.createCell(1).setCellValue(student.getUname());
            scoreRow.createCell(2).setCellValue(student.getRoutineScore());
            scoreRow.createCell(3).setCellValue(student.getReportScore());

            for (int columnIndex = 4; columnIndex < headerRow.getLastCellNum(); columnIndex++) {
                String columnName = headerRow.getCell(columnIndex).getStringCellValue();
                Integer score = student.getExperimentScores().get(columnName);
                scoreRow.createCell(columnIndex).setCellValue(score != null ? score : 0);
            }
        }

        try {
            response.setHeader("Content-Disposition", "attachment; filename=\"StudentScores.xlsx\"");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            ServletOutputStream servletOutputStream = response.getOutputStream();
            workbook.write(servletOutputStream);
            servletOutputStream.flush();
            servletOutputStream.close();

        } catch (IOException e) {
            System.out.println("写入 Excel 文件失败：" + e.getMessage());
        }
    }



    @Override
    public ReturnRes removegetExperiment(Integer eid) {


        int i =  experimentsMapper.removeExperimentByid(eid);

        if (i>0){
            return new ReturnRes(true, "删除成功");
        }

        return new ReturnRes(false, "删除失败");
    }
    @Override
    public ReturnRes releaseExperimentVm(Integer eid) {

        //先获得用户所分配的虚拟资源
        String username= SecurityContextHolder.getContext().getAuthentication().getName();

        List<VMservice> vmList=experimentsMapper.getExperiemntVmOfUser(experimentsMapper.getExperimentName(eid),username);
        System.err.println(vmList);
        if(vmList.size()==0){
            return new ReturnRes(false,  "暂无资源可释放");
        }
        int num=0;
        for (int i =0;i<vmList.size();i++){
            //释放资源
            CloudUtils.deleteVm(cloudMapper.getOpenstackByopenstackIP(vmList.get(i).getOpenstackIP()), vmList.get(i).getVmID());
            //删除数据库数据
            int count =experimentsMapper.removeVmById(vmList.get(i).getVmID());
            num+=count;
        }
        if(num>0){
            //说明释放资源了 将其加入黑名单一小时
            Date releaseDate=experimentsMapper.getReleaseTime(username);
            if(releaseDate==null){
                //第一次释放
                experimentsMapper.insertReleaseLog(username,new Date());
            }else {
                experimentsMapper.updateReleaseLog(username,new Date());
            }
        }
        return new ReturnRes(true,  "释放成功,冷却一小时后申请资源");
    }
    @Override
    public ReturnRes releaseAllExpeirmentVms() {
        List<VMservice> vmList= experimentsMapper.findAllExperimentVms();
        for (int i = 0; i <vmList.size() ; i++) {
            CloudUtils.deleteVm(cloudMapper.getOpenstackByopenstackIP(vmList.get(i).getOpenstackIP()), vmList.get(i).getVmID());
            int count =experimentsMapper.removeVmById(vmList.get(i).getVmID());
        }

        return new ReturnRes(true,  "释放成功");
    }




    @Autowired
    UserMapper userMapper;
public  List<ExperimentScores> getUsersScores(){
    List<ExperimentScores> experimentScores = experimentsMapper.getAllUserScores();
    for (int i=0;i<experimentScores.size();i++){
        List<Experiment> experimentNamesAndId = experimentsMapper.getExperimentNamesAndId();
        HashMap<String, Integer> experimentSCoreMap = new HashMap<>();
        for (Experiment e:experimentNamesAndId ) {
            Integer score= experimentsMapper.getScoreOfExperiment(e.getEid(),experimentScores.get(i).getUid());
            if(score==null){
                experimentSCoreMap.put(e.getEname(),0);
            }else {
                experimentSCoreMap.put(e.getEname(),score);
            }

        }
        experimentScores.get(i).setExperimentScores(experimentSCoreMap);;
    }
    if (experimentScores != null) {
        return experimentScores;
    }
    return null;
}


}

